#include <iostream>

#include "Library_t.h"
#include "LibraryException.h"

void bookAdmin(Library_t & library);
void borrowerAdmin(Library_t & library);

int openingMenu() {
	int x;
	cout << endl << " Library Management System " << endl
				 << " ------------------------- " << endl << endl;

	cout << endl << " Who are you? " 	<< endl
			 << "	0: Librarian " 			<< endl
			 << "	1: Borrower  " 			<< endl
			 << "	2: Help	"				<< endl
			 << "	9: Exit"				<< endl << endl;

	while (cout << "Enter your choice : " && !(cin >> x)) {
			cin.sync();
			cin.clear();
			cout << "Invalid input; please re-enter.\n";
	}

	return x;
}

void librarianMenu(Library_t & library) {
	int x;
	isbn_t isbn;
	id_t id;
	bool cont = true;
	cout << endl << " Library Management System - Librarian Menu " << endl
				 << " ------------------------------------------ " << endl << endl;

	while (cont) {
		cout << endl << " What would you like to do? " 	<< endl
				 << "	0: Book administration " 		<< endl
				 << "	1: Borrower administration  " 	<< endl
				 << "	2: Lend book  " 				<< endl
				 << "	3: Return book  " 				<< endl
				 << "	4: Library printout"			<< endl
				 << "	5: Help"						<< endl
				 << "	9: Exit to main menu"			<< endl << endl;

		while (cout << "Enter your choice : " && !(cin >> x)) {
				cin.sync();
				cin.clear();
				cout << "Invalid input; please re-enter.\n";
		}

		switch(x) {
			case 0: { bookAdmin(library); break; }
			case 1: { borrowerAdmin(library); break; }
			case 2: {
					cout << " ISBN: ";
					cin >> isbn;
					cout << " Borrower ID: ";
					cin >> id;
					try {
						if (library.lendBook(isbn,id))
							cout << " Book was lent to " << id << "!" << endl;
						else
							cout << " No available copies!\n " << id << " was added to book's waiting list!" << endl;
					} catch (LibraryException & ex) {
						cout << ex.what() << endl;
					}
					break;	}
			case 3: {
					cout << " ISBN: ";
					cin >> isbn;
					cout << " Borrower ID: ";
					cin >> id;
					try {
						library.returnBook(isbn,id);
						cout << " Book was returned successfully!" << endl;
					} catch (LibraryException & ex) {
						cout << ex.what() << endl;
					}
					break;	}
			case 4: {
					cout << library << endl;
					break;
					}
			case 5: {
					cout << endl << "Choose Book administration to add, remove and get information about books.\n" <<
									"Choose Borrower administration to add, remove and get information about borrowers.\n" <<
									"Library printout prints information about all the books and the borrowers registered\n" <<
									"to the library.\n" << endl;
					break;
					}
			case 9: cont = false;
			default: break;
		}
	}

	return;
}

void borrowerMenu(Library_t & library) {
	int x;
	bool cont = true;
	id_t id;
	string name;
	isbn_t isbn;
	const Borrower_t * tmp_borrower;
	cout << endl << " Library Management System - Borrower Menu " << endl
				 << " ----------------------------------------- " << endl << endl;

	cout << " ID: ";
	cin >> id;
	cin.sync();

	if (library.searchBorrower(id) == NULL) {
		try {
			cout << " Name: ";
			getline(cin,name,'\n');
			library.addBorrower(id,name);
			cout << endl << " You have been added to the library borrower list!" << endl;
		} catch (LibraryException & ex) {
			cout << ex.what() << endl;
			return;
		}
	}

	while(cont) {
		cout << endl << " What would you like to do? " 	<< endl
				 << "	0: Loan book  " 			<< endl
				 << "	1: Return book  " 			<< endl
				 << "	2: Personal information  " 	<< endl
				 << "	9: Exit to main menu"		<< endl << endl;

		while (cout << "Enter your choice : " && !(cin >> x)) {
				cin.sync();
				cin.clear();
				cout << "Invalid input; please re-enter.\n";
		}

		switch(x) {
			case 0: {
					cout << " ISBN: ";
					cin >> isbn;
					try {
						if (library.lendBook(isbn,id))
							cout << " The book was lent to you!" << endl;
						else
							cout << " No available Copies!\n You have been added to the book's waiting list!" << endl;
					} catch (LibraryException & ex) {
						cout << ex.what() << endl;
					}
					break;	}
			case 1: {
					cout << " ISBN: ";
					cin >> isbn;
					try {
						library.returnBook(isbn,id);
						cout << " Book was returned successfully!" << endl;
					} catch (LibraryException & ex) {
						cout << ex.what() << endl;
					}
					break;	}
			case 2: {
					if ((tmp_borrower = library.searchBorrower(id)) == NULL)
						cout << " Borrower not found! " << endl;
					else
						cout << *tmp_borrower;
					break;	}
			case 9: cont = false;
			default: break;
		}
	}

	return;
}

void bookAdmin(Library_t & library) {
	int x, num_of_copies;
	bool cont = true;
	string name, author;
	isbn_t isbn;
	const Book_t * tmp_book;
	cout << endl << " Library Management System - Book Administration " << endl
				 << " ----------------------------------------------- " << endl << endl;

	while(cont) {
		cout << endl << " What would you like to do? " 	<< endl
				 << "	0: Add book  " 		<< endl
				 << "	1: Remove book  " 	<< endl
				 << "	2: Search book  " 	<< endl
				 << "	9: Exit to librarian menu"		<< endl << endl;

		while (cout << "Enter your choice : " && !(cin >> x)) {
				cin.sync();
				cin.clear();
				cout << "Invalid input; please re-enter.\n";
		}

		switch(x) {
			case 0: {
					cout << " ISBN: ";
					cin >> isbn;
					cin.sync();
					cout << " Name: ";
					getline(cin,name,'\n');
					cout << " Author: ";
					getline(cin,author,'\n');
					cout << " Number of copies: ";
					cin >> num_of_copies;
					try {
						library.addBook(isbn,name,author,num_of_copies);
						cout << " Book was added to library!" << endl;
					} catch (LibraryException & ex) {
						cout << ex.what() << endl;
					}
					break;	}
			case 1: {
					cout << " ISBN: ";
					cin >> isbn;
					try {
						library.removeBook(isbn);
						cout << " Book was removed from library!" << endl;
					} catch (LibraryException & ex) {
						cout << ex.what() << endl;
					}
					break;	}
			case 2: {
					cout << " ISBN: ";
					cin >> isbn;
					if ((tmp_book = library.searchBook(isbn)) == NULL)
						cout << endl << " Book not found!" << endl;
					else
						cout << endl << *tmp_book << endl;
					break;	}
			case 9: cont = false;
			default: break;
		}
	}

	return;
}

void borrowerAdmin(Library_t & library) {
	int x;
	bool cont = true;
	string name;
	id_t id;
	const Borrower_t * tmp_borrower;
	cout << endl << " Library Management System - Borrower Administration " << endl
				 << " --------------------------------------------------- " << endl << endl;

	while(cont) {
		cout << endl << " What would you like to do? " 	<< endl
				 << "	0: Add borrower  " 		<< endl
				 << "	1: Remove borrower  " 	<< endl
				 << "	2: Search borrower  " 	<< endl
				 << "	9: Exit to librarian menu"		<< endl << endl;

		while (cout << "Enter your choice : " && !(cin >> x)) {
				cin.sync();
				cin.clear();
				cout << "Invalid input; please re-enter.\n";
		}

		switch(x) {
			case 0: {
					cout << " ID: ";
					cin >> id;
					cin.sync();
					cout << " Name: ";
					getline(cin,name,'\n');
					try {
						library.addBorrower(id,name);
						cout << " Borrower was added to borrowers list!" << endl;
					} catch (LibraryException & ex) {
						cout << ex.what() << endl;
					}
					break;	}
			case 1: {
					cout << " ID: ";
					cin >> id;
					try {
						library.removeBorrower(id);
						cout << " Borrower was removed from borrowers list!" << endl;
					} catch (LibraryException & ex) {
						cout << ex.what() << endl;
					}
					break;	}
			case 2: {
					cout << " ID: ";
					cin >> id;
					if ((tmp_borrower = library.searchBorrower(id)) == NULL)
						cout << " Borrower not found! " << endl;
					else
						cout << *tmp_borrower;

					break;	}
			case 9: cont = false;
			default: break;
		}
	}

	return;
}

int main() {
	Library_t library;
	bool cont	= true;			// trigger to stop loop
	unsigned int x;

	while (cont) {

		x = openingMenu();

		switch (x) {
			case 0: {librarianMenu(library); break;}
			case 1: {borrowerMenu(library); break;}
			case 2: {
					cout << endl << "Choose Librarian to get access to book and borrower administration,\nlend books to borrowers," <<
							"and return books.\nChoose Borrower for easy access to book lendings and returns, as well as\n" <<
							"getting personal information (borrower report). Be aware that to be able to\nloan books as a " <<
							"borrower, books must be added to the library by a librarian.\n"<< endl ;
					break;
					}
			case 9: cont = false;
			default: break;
		}
	}

	return 0;
}